class stl_viewer : public stl_parser
{
    public:
  stl_viewer()
    {
      result=NULL;
    }

  SoSeparator* Result()
  {
    return result;
  }
  
  
  
    private:
  void got_triangle(vector<double>& v)
  {
    
    if(!result)
      {
	pc=0;
	result= new SoSeparator;
	result-> ref();
	coords=new SoCoordinate3;
	faces=new SoFaceSet;
	result->addChild(coords);
	result->addChild(faces);
      }
    point p1(v[0],v[1],v[2]);
    point p2(v[3],v[4],v[5]);
    point p3(v[6],v[7],v[8]);

    vector<point> tri;
    
    tri.push_back(p1);
    tri.push_back(p2);
    tri.push_back(p3);

    tris.push_back(tri);
    
       
    coords->point.set1Value(pc++,v[0],v[1],v[2]);
    coords->point.set1Value(pc++,v[3],v[4],v[5]);
    coords->point.set1Value(pc++,v[6],v[7],v[8]);

    faces->numVertices.set1Value(pc/3-1,3);
    cerr<<".";
    
  }

  long pc;
  SoSeparator *result;
  SoCoordinate3 *coords;
  SoFaceSet *faces;
  
};

void Facetter::facet_tetro(long ix,long iy,long iz,
                           int v0, int v1,int v2,int v3)
{
    size_t tetro_hash=hash_tetro(ix,iy,iz,
                                 v0,v1,v2,v3);

    SoSeparator *tetro;

    if (tetras[tetro_hash]==NULL)
    {
        tetro= new SoSeparator;
        tetro->ref();
        tetras[tetro_hash]=tetro;

        result->addChild(tetro);

    }
    else
        tetro=tetras[tetro_hash];

    

    SoCoordinate3 *coords=new SoCoordinate3;
    SoFaceSet *faces=new SoFaceSet;

   
    noderef
    n0(ix,iy,iz,v0),
    n1(ix,iy,iz,v1),
    n2(ix,iy,iz,v2),
    n3(ix,iy,iz,v3);


    int triindex = 0;
    if (nodes[n0]==SOLID) triindex |= 1;
    if (nodes[n1]==SOLID) triindex |= 2;
    if (nodes[n2]==SOLID) triindex |= 4;
    if (nodes[n3]==SOLID) triindex |= 8;

    /* Form the vertices of the triangles for each case */
    int i=0,j=0;

    switch (triindex)
    {
    case 0x00: //0000
    case 0x0F: //1111
        break;
    case 0x0E: //1110
        coords->point.set1Value(i++,intersect(n0,n3));//0 3 *
        coords->point.set1Value(i++,intersect(n0,n2));//0 2 *
        coords->point.set1Value(i++,intersect(n0,n1));//0 1 *
        faces->numVertices.set1Value(j++,3);
        break;
    case 0x01: //0001
        coords->point.set1Value(i++,intersect(n0,n1));//0 1
        coords->point.set1Value(i++,intersect(n0,n2));//0 2
        coords->point.set1Value(i++,intersect(n0,n3));//0 3
        faces->numVertices.set1Value(j++,3);
        break;
    case 0x0D: //1101
        coords->point.set1Value(i++,intersect(n1,n2));//1 2 *
        coords->point.set1Value(i++,intersect(n1,n3));//1 3 *
        coords->point.set1Value(i++,intersect(n1,n0));//1 0 *
        faces->numVertices.set1Value(j++,3);
        break;
    case 0x02: //0010
        coords->point.set1Value(i++,intersect(n1,n0));//1 0
        coords->point.set1Value(i++,intersect(n1,n3));//1 3
        coords->point.set1Value(i++,intersect(n1,n2));//1 2
        faces->numVertices.set1Value(j++,3);
        break;
    case 0x0C: //1100
        coords->point.set1Value(i++,intersect(n1,n3));//1 3 *
        coords->point.set1Value(i++,intersect(n0,n2));//0 2 *
        coords->point.set1Value(i++,intersect(n0,n3));//0 3 *
        faces->numVertices.set1Value(j++,3);
        coords->point.set1Value(i++,coords->point[1]);//    *
        coords->point.set1Value(i++,intersect(n1,n2));//1 2 *
        coords->point.set1Value(i++,coords->point[0]);//    *
        faces->numVertices.set1Value(j++,3);
        break;
    case 0x03: //0011
        coords->point.set1Value(i++,intersect(n0,n3));//0 3
        coords->point.set1Value(i++,intersect(n0,n2));//0 2
        coords->point.set1Value(i++,intersect(n1,n3));//1 3
        faces->numVertices.set1Value(j++,3);
        coords->point.set1Value(i++,coords->point[2]);
        coords->point.set1Value(i++,intersect(n1,n2));//1 2
        coords->point.set1Value(i++,coords->point[1]);
        faces->numVertices.set1Value(j++,3);
        break;
    case 0x0B: //1011
        coords->point.set1Value(i++,intersect(n2,n3));//2 3 *
        coords->point.set1Value(i++,intersect(n2,n1));//2 1 *
        coords->point.set1Value(i++,intersect(n2,n0));//2 0 *
        faces->numVertices.set1Value(j++,3);
        break;
    case 0x04: //0100
        coords->point.set1Value(i++,intersect(n2,n0));//2 0
        coords->point.set1Value(i++,intersect(n2,n1));//2 1
        coords->point.set1Value(i++,intersect(n2,n3));//2 3
        faces->numVertices.set1Value(j++,3);
        break;
    case 0x0A: //1010
        coords->point.set1Value(i++,intersect(n0,n3));//0 3 *
        coords->point.set1Value(i++,intersect(n2,n3));//2 3 *
        coords->point.set1Value(i++,intersect(n0,n1));//0 1 *
        faces->numVertices.set1Value(j++,3);
        coords->point.set1Value(i++,coords->point[1]);//    *
        coords->point.set1Value(i++,intersect(n1,n2));//1 2 *
        coords->point.set1Value(i++,coords->point[2]);//    *
        break;
    case 0x05: //0101
        coords->point.set1Value(i++,intersect(n0,n1));//0 1
        coords->point.set1Value(i++,intersect(n2,n3));//2 3
        coords->point.set1Value(i++,intersect(n0,n3));//0 3
        faces->numVertices.set1Value(j++,3);
        coords->point.set1Value(i++,coords->point[0]);
        coords->point.set1Value(i++,intersect(n1,n2));//1 2
        coords->point.set1Value(i++,coords->point[1]);
        faces->numVertices.set1Value(j++,3);
        break;
    case 0x09: //1001
        coords->point.set1Value(i++,intersect(n2,n3));//2 3 *
        coords->point.set1Value(i++,intersect(n1,n3));//1 3 *
        coords->point.set1Value(i++,intersect(n0,n1));//0 1 *
        faces->numVertices.set1Value(j++,3);
        coords->point.set1Value(i++,coords->point[0]);//    *
        coords->point.set1Value(i++,intersect(n0,n2));//0 2 *
        coords->point.set1Value(i++,coords->point[2]);//    *
        faces->numVertices.set1Value(j++,3);
        break;
    case 0x06: //0110
        coords->point.set1Value(i++,intersect(n0,n1));//0 1
        coords->point.set1Value(i++,intersect(n1,n3));//1 3
        coords->point.set1Value(i++,intersect(n2,n3));//2 3
        faces->numVertices.set1Value(j++,3);
        coords->point.set1Value(i++,coords->point[0]);
        coords->point.set1Value(i++,intersect(n0,n2));//0 2
        coords->point.set1Value(i++,coords->point[2]);
        faces->numVertices.set1Value(j++,3);
        break;
    case 0x07: //0111
        coords->point.set1Value(i++,intersect(n3,n1));//3 1 *
        coords->point.set1Value(i++,intersect(n3,n2));//3 2 *
        coords->point.set1Value(i++,intersect(n3,n0));//3 0 *
        faces->numVertices.set1Value(j++,3);
        break;
    case 0x08: //1000
        coords->point.set1Value(i++,intersect(n3,n0));//3 0
        coords->point.set1Value(i++,intersect(n3,n2));//3 2
        coords->point.set1Value(i++,intersect(n3,n1));//3 1
        faces->numVertices.set1Value(j++,3);
        break;
    }
    tetro->removeAllChildren();
    tetro->addChild(coords);
    tetro->addChild(faces);
   
}

void pm(SoSeparator *r, float c[3])
{

    SoSeparator *node= new SoSeparator;
    node->ref();
    SoTransform *tr=new SoTransform;
    tr->translation.setValue(c);
    SoMaterial *mat= new SoMaterial;
    mat->diffuseColor=SbColor(0,1,0);
    SoSphere *sp=new SoSphere;
    sp->radius=0.05;

    node->addChild(tr);
    node->addChild(mat);
    node->addChild(sp);
    r->addChild(node);
}
